from flask import Blueprint, jsonify, request
import os
import shutil
import glob
from datetime import datetime
from pathlib import Path

# 创建蓝图
data_cleanup_bp = Blueprint('data_cleanup', __name__)

def get_data_directory():
    """获取backend/data目录的绝对路径"""
    backend_dir = os.path.dirname(os.path.dirname(__file__))
    return os.path.join(backend_dir, 'data')

def get_directory_info(path, relative_path="", max_depth=2, current_depth=0):
    """获取目录信息，支持递归获取子目录，限制递归深度避免性能问题"""
    if not os.path.exists(path):
        print(f"  {'  ' * current_depth}目录不存在: {path}")
        return {
            'exists': False,
            'size': 0,
            'file_count': 0,
            'subdirs': []
        }
    
    total_size = 0
    file_count = 0
    subdirs = []
    
    try:
        # 获取目录中的所有项目
        try:
            items = os.listdir(path)
        except PermissionError as e:
            print(f"权限错误，无法列出目录内容: {e}")
            return {
                'exists': True,
                'size': 0,
                'file_count': 0,
                'subdirs': []
            }
        except Exception as e:
            print(f"列出目录内容时出错: {e}")
            return {
                'exists': True,
                'size': 0,
                'file_count': 0,
                'subdirs': []
            }
        
        for item in items:
            item_path = os.path.join(path, item)
            item_relative_path = os.path.join(relative_path, item) if relative_path else item
            
            try:
                if os.path.isdir(item_path):
                    # 计算子目录的大小和文件数
                    subdir_file_count, subdir_size = count_directory_files(item_path)
                    
                    # 准备子目录信息
                    subdir_data = {
                        'name': item,
                        'path': item_relative_path,
                        'size': subdir_size,
                        'size_formatted': format_size(subdir_size),
                        'file_count': subdir_file_count,
                        'subdirs': []
                    }
                    
                    # 如果还没达到最大深度，递归获取子目录
                    if current_depth < max_depth:
                        try:
                            subdir_info = get_directory_info(item_path, item_relative_path, max_depth, current_depth + 1)
                            subdir_data['subdirs'] = subdir_info['subdirs']
                        except (OSError, IOError) as e:
                            print(f"递归获取子目录失败: {e}")
                            pass
                    
                    subdirs.append(subdir_data)
                elif os.path.isfile(item_path):
                    # 计算根目录下的文件
                    try:
                        file_size = os.path.getsize(item_path)
                        total_size += file_size
                        file_count += 1
                    except (OSError, IOError):
                        pass
            except Exception as e:
                print(f"处理项目时出错 {item}: {e}")
                continue
                
    except (OSError, IOError) as e:
        print(f"获取目录信息时出错: {e}")
    except Exception as e:
        print(f"未预期的错误: {e}")
    
    # 累加所有子目录的大小和文件数到总计中
    for subdir in subdirs:
        total_size += subdir['size']
        file_count += subdir['file_count']
    
    return {
        'exists': True,
        'size': total_size,
        'file_count': file_count,
        'subdirs': subdirs
    }

def count_directory_files(directory_path):
    """
    统计目录中的文件数量和总大小，不删除任何文件
    返回 (文件数量, 总大小)
    """
    file_count = 0
    total_size = 0
    
    try:
        for root, dirs, files in os.walk(directory_path):
            for file in files:
                file_path = os.path.join(root, file)
                try:
                    size = os.path.getsize(file_path)
                    file_count += 1
                    total_size += size
                except (OSError, IOError):
                    # 忽略无法访问的文件
                    continue
    except (OSError, IOError):
        # 忽略无法访问的目录
        pass
    
    return file_count, total_size

def clean_directory_files(directory_path):
    """
    清理目录中的所有文件，但保留目录结构
    返回 (清理的文件数量, 释放的空间大小)
    """
    cleaned_count = 0
    total_size = 0
    
    try:
        for root, dirs, files in os.walk(directory_path):
            for file in files:
                file_path = os.path.join(root, file)
                try:
                    size = os.path.getsize(file_path)
                    os.remove(file_path)
                    cleaned_count += 1
                    total_size += size
                except (OSError, IOError) as e:
                    # 记录无法删除的文件，但继续处理其他文件
                    print(f"无法删除文件 {file_path}: {e}")
                    continue
    except (OSError, IOError) as e:
        print(f"清理目录时出错 {directory_path}: {e}")
    
    return cleaned_count, total_size

def format_size(size_bytes):
    """格式化文件大小"""
    if size_bytes == 0:
        return "0 B"
    size_names = ["B", "KB", "MB", "GB", "TB"]
    import math
    i = int(math.floor(math.log(size_bytes, 1024)))
    p = math.pow(1024, i)
    s = round(size_bytes / p, 2)
    return f"{s} {size_names[i]}"

@data_cleanup_bp.route('/status', methods=['GET'])
def get_data_status():
    """获取data目录状态信息"""
    try:
        data_dir = get_data_directory()
        
        # 检查目录权限
        if os.path.exists(data_dir):
            try:
                # 测试目录访问权限
                os.listdir(data_dir)
            except PermissionError as e:
                return jsonify({
                    'success': False,
                    'error': f'没有权限访问目录: {data_dir}'
                }), 403
            except Exception as e:
                return jsonify({
                    'success': False,
                    'error': f'无法访问目录: {e}'
                }), 500
        
        info = get_directory_info(data_dir)
        
        # 格式化返回数据
        result = {
            'success': True,
            'data': {
                'path': data_dir,
                'exists': info['exists'],
                'total_size': info['size'],
                'total_size_formatted': format_size(info['size']),
                'total_files': info['file_count'],
                'subdirectories': info['subdirs']
            }
        }
        
        return jsonify(result)
        
    except Exception as e:
        print(f"获取数据状态时发生异常: {e}")
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500

@data_cleanup_bp.route('/clean', methods=['POST'])
def clean_data():
    """清理data目录"""
    try:
        data = request.get_json() or {}
        clean_type = data.get('type', 'all')  # all, specific, logs, detection, rootheal, defect
        specific_paths = data.get('paths', [])
        confirm = data.get('confirm', False)
        
        if not confirm:
            return jsonify({
                'success': False,
                'error': '需要确认操作'
            }), 400
        
        data_dir = get_data_directory()
        cleaned_items = []
        total_size_freed = 0
        
        if clean_type == 'all':
            # 清理整个data目录中的所有文件，但保留目录结构
            if os.path.exists(data_dir):
                for item in os.listdir(data_dir):
                    item_path = os.path.join(data_dir, item)
                    if os.path.isdir(item_path):
                        # 清理子目录中的文件
                        cleaned_count, size = clean_directory_files(item_path)
                        if cleaned_count > 0:
                            cleaned_items.append({
                                'type': 'directory',
                                'name': item,
                                'size': size,
                                'file_count': cleaned_count
                            })
                            total_size_freed += size
                        
        elif clean_type == 'specific':
            # 清理指定路径中的文件，保留目录结构
            for path in specific_paths:
                full_path = os.path.join(data_dir, path)
                if os.path.exists(full_path):
                    if os.path.isdir(full_path):
                        cleaned_count, size = clean_directory_files(full_path)
                        if cleaned_count > 0:
                            cleaned_items.append({
                                'type': 'directory',
                                'name': path,
                                'size': size,
                                'file_count': cleaned_count
                            })
                            total_size_freed += size
                    else:
                        size = os.path.getsize(full_path)
                        os.remove(full_path)
                        cleaned_items.append({
                            'type': 'file',
                            'name': path,
                            'size': size
                        })
                        total_size_freed += size
                        
        elif clean_type in ['logs', 'detection', 'rootheal', 'defect']:
            # 清理特定类型的目录中的文件，保留目录结构
            dir_mapping = {
                'logs': 'logs',
                'detection': 'detection_data',
                'rootheal': 'rootheal_data',
                'defect': 'DefectIdentification_data'
            }
            
            target_dir = dir_mapping.get(clean_type)
            if target_dir:
                target_path = os.path.join(data_dir, target_dir)
                if os.path.exists(target_path):
                    cleaned_count, size = clean_directory_files(target_path)
                    if cleaned_count > 0:
                        cleaned_items.append({
                            'type': 'directory',
                            'name': target_dir,
                            'size': size,
                            'file_count': cleaned_count
                        })
                        total_size_freed += size
        
        return jsonify({
            'success': True,
            'data': {
                'cleaned_items': cleaned_items,
                'total_items': len(cleaned_items),
                'total_size_freed': total_size_freed,
                'total_size_freed_formatted': format_size(total_size_freed),
                'clean_type': clean_type,
                'timestamp': datetime.now().isoformat()
            }
        })
        
    except Exception as e:
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500

@data_cleanup_bp.route('/preview', methods=['POST'])
def preview_clean():
    """预览清理操作 - 不实际删除文件"""
    try:
        data = request.get_json() or {}
        clean_type = data.get('type', 'all')
        specific_paths = data.get('paths', [])
        
        data_dir = get_data_directory()
        
        
        preview_items = []
        total_size_to_free = 0
        
        if clean_type == 'all':
            # 预览清理整个data目录中的所有文件
            if os.path.exists(data_dir):
                for item in os.listdir(data_dir):
                    item_path = os.path.join(data_dir, item)
                    if os.path.isdir(item_path):
                        file_count, size = count_directory_files(item_path)
                        if file_count > 0:
                            preview_items.append({
                                'type': 'directory',
                                'name': item,
                                'path': item,
                                'size': size,
                                'size_formatted': format_size(size),
                                'file_count': file_count
                            })
                            total_size_to_free += size
                    
        elif clean_type == 'specific':
            # 预览清理指定路径中的文件
            for path in specific_paths:
                full_path = os.path.join(data_dir, path)
                
                if os.path.exists(full_path):
                    if os.path.isdir(full_path):
                        file_count, size = count_directory_files(full_path)
                        if file_count > 0:
                            preview_items.append({
                                'type': 'directory',
                                'name': os.path.basename(path),
                                'path': path,
                                'size': size,
                                'size_formatted': format_size(size),
                                'file_count': file_count
                            })
                            total_size_to_free += size
                    else:
                        size = os.path.getsize(full_path)
                        preview_items.append({
                            'type': 'file',
                            'name': os.path.basename(path),
                            'path': path,
                            'size': size,
                            'size_formatted': format_size(size),
                            'file_count': 1
                        })
                        total_size_to_free += size
                        
        elif clean_type in ['logs', 'detection', 'rootheal', 'defect']:
            # 预览清理特定类型的目录中的文件
            dir_mapping = {
                'logs': 'logs',
                'detection': 'detection_data',
                'rootheal': 'rootheal_data',
                'defect': 'DefectIdentification_data'
            }
            
            target_dir = dir_mapping.get(clean_type)
            if target_dir:
                target_path = os.path.join(data_dir, target_dir)
                if os.path.exists(target_path):
                    file_count, size = count_directory_files(target_path)
                    if file_count > 0:
                        preview_items.append({
                            'type': 'directory',
                            'name': target_dir,
                            'path': target_dir,
                            'size': size,
                            'size_formatted': format_size(size),
                            'file_count': file_count
                        })
                        total_size_to_free = size
        
        
        return jsonify({
            'success': True,
            'data': {
                'preview_items': preview_items,
                'total_items': len(preview_items),
                'total_size_to_free': total_size_to_free,
                'total_size_to_free_formatted': format_size(total_size_to_free),
                'clean_type': clean_type
            }
        })
        
    except Exception as e:
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500
